﻿using Ec.NETCoreFramework.Common.Core;
using Ec.NETCoreFramework.Common.Core.Helpers;
using Ec.NETCoreFramework.Common.Core.Utilities;
using SshNet.Security.Cryptography;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Ec.NETCoreFramework.Common.Clients
{

    /// <summary>
    /// api 请求client
    /// </summary>
    public class ApiRequestClient
    {
        private static string AppId = string.Empty;

        private static string Secret = string.Empty;

        public ApiRequestClient(RequestAppSecret appSecret)
        {
            AppId = appSecret.AppId;
            Secret = appSecret.Secret;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="apiName"></param>
        /// <param name="param"></param>
        /// <param name="format"></param>
        /// <param name="version"></param>
        /// <returns></returns>
        public Dictionary<string, object> GetSign(string apiName, Dictionary<string, object> param, FormatType format = FormatType.Json, string version = "3.0")
        {
            param = param ?? new Dictionary<string, object>();
            param = param.ToOrdinalIgnoreCase();
            param.Add("appid", AppId);
            param.Add("method", apiName);
            param.Add("timestamp", Time.GetTimstamp().ToString());
            param.Add("v", version);

            param.Add("format", format.ToString());

            var sordDic = param.SortFilter();
            string sign = Encrypt.Md5By32(sordDic.ToLinkString(Encoding.UTF8) + "&secret=" + Secret);
            param.Add("sign", sign);
            return param;
        }


        /// <summary>
        /// 返回response
        /// </summary>
        /// <param name="path"></param>
        /// <param name="actionName"></param>
        /// <param name="parameters"></param>
        /// <param name="route"></param>
        /// <param name="header"></param>
        /// <returns></returns>
        public async Task<IResponse> GetResponse<T>(string path, string actionName, Dictionary<string, object> parameters, string route = "/Route.axd", Dictionary<string, string> header = null, int timeOut = 1000)
        {
            IResponse response = null;
            string msg = string.Empty;
            var content = GetSign(actionName, parameters);


            if (!path.StartsWith("http"))
            {
                path = "http://" + path;
            }
            string url = path + route;

            var client = new WebClient<IResponse>().Post(url);
            if (header != null)
            {
                foreach (KeyValuePair<string, string> kv in header)
                {
                    client.Header(kv.Key, kv.Value);
                }
            }
            client.Header("Connection", "Keep-Alive");
            client.Header("Keep-Alive", "timeout=1000");

            client.Timeout(timeOut);
            client.FormData(content);
            client.OnSuccess((s) =>
            {

            }, (r) =>
            {
                LoggerHelper.Instance.Information(r);
                response = ParseResponseData<T>(r);
                return response;
            });

            client.OnFail((s,code) =>
            {
                if (code == HttpStatusCode.OK)
                {
                    response = ParseResponseData<string>(s);
                }
                else
                {
                    response = FrameworkResponse.SystemError(s);
                }
                LoggerHelper.Instance.Error(s);
            });
            await client.ResultAsync();
            return response ?? FrameworkResponse.SystemError("请求错误");


        }
        public async Task<IResponse> PostBinary<T>(string path, string actionName, Dictionary<string, object> parameters, string route = "/Route.axd", Dictionary<string, string> header = null, int timeOut = 1000)
        {
            IResponse response = null;
            string msg = string.Empty;
            var content = GetSign(actionName, parameters);


            if (!path.StartsWith("http"))
            {
                path = "http://" + path;
            }
            string url = path + route;

            var client = new WebClient<IResponse>().Post(url);
            if (header != null)
            {
                foreach (KeyValuePair<string, string> kv in header)
                {
                    client.Header(kv.Key, kv.Value);
                }
            }
            client.Header("Connection", "Keep-Alive");
            client.Header("Keep-Alive", "timeout=1000");

            client.Timeout(timeOut);
            client.BinaryData(content);
            client.OnSuccess((s) =>
            {

            }, (r) =>
            {
                LoggerHelper.Instance.Information(r);
                response = ParseResponseData<T>(r);
                return response;
            });

            client.OnFail((s,code) =>
            {
                if (code == HttpStatusCode.OK)
                {
                    response = ParseResponseData<string>(s);
                }
                else
                {
                    response = FrameworkResponse.SystemError(s);
                }
                LoggerHelper.Instance.Error(s);
            });
            await client.ResultAsync();
            return response ?? FrameworkResponse.SystemError("请求错误");


        }
        /// <summary>
        /// 解析返回数据
        /// </summary>
        /// <param name="content"></param>
        /// <returns></returns>
        public static IResponse ParseResponseData<T>(string content)
        {
            IResponse result = null;

            try
            {
                var dic = Json.ToObject<Dictionary<string, object>>(content);
                if (!dic.ContainsKey("Success")) return FrameworkResponse.SystemError("不是有效对象");
                string message = Utils.ToString(dic["Message"]);
                int code = Core.Helpers.Convert.ToInt(dic["Code"]);
                if (Core.Helpers.Convert.ToBool(dic["Success"]))
                {

                    if (dic["Content"] == null)
                    {
                        return FrameworkResponse.Success(default(T), message);
                    }
                    string name = dic["Content"].GetType().Name;

                    if (name == "String" || typeof(T).Name == "String")
                    {
                        result = FrameworkResponse.Success(dic["Content"].ToString(), message);
                    }
                    else if (name == "JObject" || name == "JArray")
                    {
                        result = FrameworkResponse.Success(Json.ToObject<T>(dic["Content"].ToString()), message);
                    }
                    else
                    {
                        result = FrameworkResponse.Success(dic["Content"], message);
                    }
                }
                else
                {
                    result = FrameworkResponse.SystemErrorData(code, message);
                    //result = FrameworkResponse.SystemError(message);
                }
            }
            catch (Exception ex)
            {

                result = FrameworkResponse.SystemErrorData(500, ex.Message);
            }
            return result;
        }

    }
    /// <summary>
    /// 开放平台输出类型
    /// </summary>
    [Serializable]
    public enum FormatType
    {
        /// <summary>
        /// json格式
        /// </summary>
        Json,
        /// <summary>
        /// XML格式
        /// </summary>
        Xml,
        /// <summary>
        /// 二进制流
        /// </summary>
        Binary,
        /// <summary>
        /// 纯文本
        /// </summary>
        Text
    }
}
